package org.oep.bluetooth;
import java.io.IOException;
import java.util.Vector;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;

public class BTHandler implements DiscoveryListener {
	private static LocalDevice me;
	private static DiscoveryAgent agent;
	
	private Vector devicesToScan = new Vector();
	private boolean antennaBusy = false;
	private BluetoothClient client;

	public BTHandler() {
		initialize();
	}
	
	/*
	 * Inherited from Runnable
	 */
	//--------------------------------------------------------------//
	
	
	/*
	 * Inherited from DiscoveryListener
	 */
	//--------------------------------------------------------------//
	
	public void deviceDiscovered(RemoteDevice device, DeviceClass type) {
		if(!devicesToScan.contains(device))
			devicesToScan.addElement(device);				
	}

	public void inquiryCompleted(int exitCode) {
		switch(exitCode) {
		case DiscoveryListener.INQUIRY_ERROR:
		case DiscoveryListener.INQUIRY_TERMINATED:
			devicesToScan.removeAllElements();
			antennaBusy = false;
			if(client != null) client.receiveDeviceList(null);
			return;
		}
		
		Vector devices = new Vector();
		for(int i = 0; i < devicesToScan.size(); i++) {
			RemoteDevice device = (RemoteDevice) devicesToScan.elementAt(i);
			String address = device.getBluetoothAddress().toUpperCase();
			
			// First: Get the device name, skip if we couldn't find it
			String name;
			try {
				name = device.getFriendlyName(false);
			}
			catch(IOException e) {
				continue;
			}
			
			// If we already have it and the old name is the default name, update to the new one
			devices.addElement( new Device(address, name) );
		}
		devicesToScan.removeAllElements();
		
		antennaBusy = false;
		if(client != null) client.receiveDeviceList(devices);
	}

	public void serviceSearchCompleted(int arg0, int arg1) {
		
	}

	public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {

	}

	
	/*
	 * Helper functions for Bluetooth scans
	 */
	//--------------------------------------------------------------//
	
	public void doNewSearch(BluetoothClient c) {
		devicesToScan.removeAllElements();
		client = c;

		try {
			antennaBusy = agent.startInquiry(DiscoveryAgent.GIAC, this);
		}
		catch(Exception e) {
			System.err.println(e);
			client.receiveDeviceList(null);
		}

	}
	
	public void stopScan() {
		// If we stop a scan, let's wait a bit before we start a new one
		if(antennaBusy) {
			agent.cancelInquiry(this);
			antennaBusy = false;
		}
		else
			agent.cancelInquiry(this);
			
		if(!antennaBusy)
			try { Thread.sleep(100); } catch(Exception e) { }
	}
	
	public boolean antennaIsBusy() {
		return antennaBusy;
	}
	
	public boolean initialize() {
		try {
			agent = LocalDevice.getLocalDevice().getDiscoveryAgent();
			me = LocalDevice.getLocalDevice();
		} catch(Exception e) {
			System.err.println(e);
		}
		return isInitialized();
	}
	
	public boolean isInitialized() {
		return agent != null && me != null;
	}
	
	public static boolean supportsBluetooth() {
		DiscoveryAgent a = null;
		LocalDevice b = null;
		try {
			a = LocalDevice.getLocalDevice().getDiscoveryAgent();
			b = LocalDevice.getLocalDevice();
		} catch(Exception e) {
			System.err.println(e);
		}
		return a != null && b != null;
	}
	
	public String getMyMAC() {
		if(me != null)
			return me.getBluetoothAddress();
		else return null;
	}
	
	public String getMyDeviceName() {
		if(me != null)
			return me.getFriendlyName();
		else
			return null;
	}
}
